#pragma once
#include <deque>
#include <math.h>
#include <iostream>
#include "Bit.h"

using namespace std;

/**
*	The class Bitstr inherits many functions from the STL-class deque<Bit>.
*	This makes it possible to add/remove both at the front and the back of the container, making the diffrent manipulations easier.
*	The class is a container of Bit-objects, making up a binary "word". 
*	It contains functions for printing, adding two strings and performing twocomplement to be able to represent negative integers as binary.
*/

class Bitstr : public deque<Bit>
{
public:

	Bitstr(void)
	{
	}

	~Bitstr(void)
	{
	}

	void print()
	{
		for( int i = 0; i < this->size(); i++)
		{
			cout << this->operator[](i).GetValue() << " ";
		}
		cout << endl;
	}

	void addstr( Bitstr bstr, Bitstr *sumstr )
	{
		Bitstr::iterator it;
		sumstr->clear();

		Bit *sum = new Bit();
		Bit *cu = new Bit();
		Bit ci;
		Bit padding('0');

		// Check if one Bitstr is larger then the other, and insert padding before MSB

		if( this->size() > bstr.size() )
		{
			for( int i = bstr.size(); i < this->size(); i++ )
			{
				bstr.insert(bstr.begin(), padding);
			}
		}
		if( bstr.size() > this->size() )
		{
			for( int i = this->size(); i < bstr.size(); i++ )
			{
				this->insert(this->begin(), padding);
			}
		}

		for( int i = this->size()-1; i >= 0; i-- )
		{
			ci = *cu;
			this->operator[](i).add(bstr[i],ci,sum,cu);
			sumstr->push_front(*sum);
		}
		// sumstr->push_front(*cu); Not used when using fixed wordlength.
	}

	Bitstr* twocomp( int wordLength )
	{
		Bitstr theOne;
		Bitstr *newSum = new Bitstr();
	/*	for( auto it : *this )
		{
			if( it.GetValue() == '1' )
				it.SetValue('0');
			else
				it.SetValue('1');
		}*/

		for( int i = 0; i < wordLength; i++ )
		{
			if( (*this)[i].GetValue() == '0' )
				(*this)[i].SetValue('1');
			else
				(*this)[i].SetValue('0');
		}

		theOne.push_front( Bit('1') );

		for( int i = 0; i < wordLength -1; i++ )
		{
			theOne.push_front( Bit('0') );
		}


		(*this).addstr(theOne, newSum );
		return newSum;

	}
};

